﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System.ComponentModel;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.UI.ViewModel.Data;

#endregion

namespace ScrumTable.UI.ViewModel
{
    /// <summary>
    /// User story for the View model
    /// </summary>
    public class ProjectViewModel : ViewModelBase, IViewModelData<Project>
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        /// <summary>
        /// The Project from the BL.
        /// </summary>
        private readonly Project _project;
        private readonly ScrumViewModelData _scrumData;
        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the original instance.
        /// </summary>
        public Project Original { get { return _project; } }

        /// <summary>
        /// Gets the id of the project.
        /// </summary>
        public string Id
        {
            get { return _project.Id; }
        }

        /// <summary>
        /// Gets or sets the name of the project.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get { return _project.Name; }
            set
            {
                _project.Name = value;
                SendPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Gets the name of the parent of the project.
        /// </summary>
        public string Parent
        {
            get
            {
                if (_project.Parent == null)
                    return "...";
                return _project.Parent.Id;
            }
        }

        /// <summary>
        /// Gets all Iterations from this Project
        /// </summary>
        /// <value>The iterations.</value>
        public ObservableDomainCollection<IterationViewModel, Iteration> Iterations
        {
            get
            {
                var iterations = new ObservableDomainCollection<IterationViewModel, Iteration>();
                iterations.Fill(_project.Iterations, iteration => new IterationViewModel(iteration, _scrumData));
                return iterations;
            }
        }

        /// <summary>
        /// Gets the members from this project.
        /// </summary>
        /// <value>The members.</value>
        public ObservableDomainCollection<MemberViewModel, Member> Members
        {
            get
            {
                var members = new ObservableDomainCollection<MemberViewModel, Member>();
                members.Fill(_project.Members, member => new MemberViewModel(member));
                return members;
            }
        }

        /// <summary>
        /// Gets the stories from this project.
        /// </summary>
        /// <value>The stories.</value>
        public ObservableDomainCollection<UserStoryViewModel, UserStory> Stories
        {
            get
            {
                var stories = new ObservableDomainCollection<UserStoryViewModel, UserStory>();
                stories.Fill(_project.Stories, story => new UserStoryViewModel(story));
                return stories;
            }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="ProjectViewModel"/> class.
        /// </summary>
        /// <param name="project">The project.</param>
        /// <param name="scrumData">The scrum view model data.</param>
        public ProjectViewModel(Project project, ScrumViewModelData scrumData)
        {
            _scrumData = scrumData;
            _project = project;
            _project.PropertyChanged += OnProjectPropertyChanged;
        }

        /// <summary>
        /// Releases the managed resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            _project.PropertyChanged -= OnProjectPropertyChanged;
            _project.Dispose();
            base.ReleaseManagedResources();
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Saves this instance.
        /// </summary>
        public void Save()
        {
            Original.Save();
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        private void OnProjectPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SendPropertyChanged(e.PropertyName);
        }

        #endregion

        #region Reshaper: Equals
        /// <summary>
        /// Equalses the specified other.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        public bool Equals(ProjectViewModel other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other._project, _project);
        }

        /// <summary>
        /// Determines whether the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// true if the specified <see cref="T:System.Object"/> is equal to the current <see cref="T:System.Object"/>; otherwise, false.
        /// </returns>
        /// <param name="obj">The <see cref="T:System.Object"/> to compare with the current <see cref="T:System.Object"/>. 
        ///                 </param><exception cref="T:System.NullReferenceException">The <paramref name="obj"/> parameter is null.
        ///                 </exception><filterpriority>2</filterpriority>
        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (ProjectViewModel)) return false;
            return Equals((ProjectViewModel) obj);
        }

        /// <summary>
        /// Serves as a hash function for a particular type. 
        /// </summary>
        /// <returns>
        /// A hash code for the current <see cref="T:System.Object"/>.
        /// </returns>
        /// <filterpriority>2</filterpriority>
        public override int GetHashCode()
        {
            return (_project != null ? _project.GetHashCode() : 0);
        }

        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator ==(ProjectViewModel left, ProjectViewModel right)
        {
            return Equals(left, right);
        }

        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="left">The left.</param>
        /// <param name="right">The right.</param>
        /// <returns>The result of the operator.</returns>
        public static bool operator !=(ProjectViewModel left, ProjectViewModel right)
        {
            return !Equals(left, right);
        }
        #endregion
    }
}